package utils

import (
	"errors"
	"fmt"
	"gitee.com/aqchain/go-ethereum/common"
	"gitee.com/aqchain/go-ethereum/common/hexutil"
	"gitee.com/aqchain/go-ethereum/crypto"
	"gitee.com/aqchain/go-ethereum/signer/core"
	"log"
	"strings"
)

// Fatal 简化错误判断 抛出异常
func Fatal(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

// recover 以太坊恢复签名地址
func recover(msg, hexSig string) (common.Address, error) {
	sig, err := hexutil.Decode(hexSig)
	if err != nil {
		return common.Address{}, err
	}

	if len(sig) != 65 {
		return common.Address{}, fmt.Errorf("signature must be 65 bytes long")
	}
	if sig[64] != 27 && sig[64] != 28 {
		return common.Address{}, fmt.Errorf("invalid Ethereum signature (V is not 27 or 28)")
	}
	sig[64] -= 27 // Transform yellow paper V from 27/28 to 0/1

	hash, _ := core.SignHash([]byte(msg))
	rpk, err := crypto.Ecrecover(hash, sig)
	if err != nil {
		return common.Address{}, err
	}
	pubKey := crypto.ToECDSAPub(rpk)
	recoveredAddr := crypto.PubkeyToAddress(*pubKey)
	return recoveredAddr, nil
}

func VerifySignature(address, message, signature string) error {
	recoveredAddress, err := recover(message, signature)
	if err != nil {
		return err
	}
	if strings.ToLower(address) != strings.ToLower(recoveredAddress.String()) {
		return errors.New("签名错误")
	}
	return nil
}
